/*
 * elf/elf.hh - ELF data types.
 * Copyright (C) 2007  Mikhail Vorozhtsov
 * See the LICENSE section of the README file for details.
 */

/* $Id$ */

#ifndef HEADER_ELF_ELF_HH
#define HEADER_ELF_ELF_HH

START_NAMESPACE (elf)

struct hdr_t
{
  enum class_t
  {
    CLASS_NONE = 0,
    CLASS_32 = 1,
    CLASS_64 = 2
  };

  enum data_t
  {
    DATA_NONE = 0,
    DATA_2LSB = 1,
    DATA_2MSB = 2
  };

  enum version_t
  {
    VERSION_NONE = 0,
    VERSION_CURRENT = 1
  };

  enum os_abi_t
  {
    OS_ABI_SYSV = 0
  };

  enum type_t
  {
    TYPE_NONE = 0,
    TYPE_REL = 1,
    TYPE_EXEC = 2,
    TYPE_DYN = 3,
    TYPE_CORE = 4
  };

  enum machine_t
  {
    MACHINE_NONE = 0,
    MACHINE_X86_64 = 62
  };

  enum shn_t
  {
    SHN_UNDEF = 0,
    SHN_ABS = 0xfff1
  };

  struct
    {
      u8_t m0;
      u8_t m1;
      u8_t m2;
      u8_t m3;
      u8_t clazz;
      u8_t data;
      u8_t elf_version;
      u8_t os_abi;
      u8_t api_version;
      u8_t pad;
      u8_t brand;
      u8_t unused[5];
    } PACKED;
  u16_t type;
  u16_t machine;
  u32_t version;
  u64_t entry;
  u64_t phoff;
  u64_t shoff;
  u32_t flags;
  u16_t ehsize;
  u16_t phentsize;
  u16_t phnum;
  u16_t shentsize;
  u16_t shnum;
  u16_t shstrndx;

  INLINE
  bool
  elf_p ()
  {
    return m0 == 0x7f && m1 == 'E' && m2 == 'L' && m3 == 'F';
  }
} PACKED;

struct shdr_t
{
  enum idx_t
  {
    IDX_UNDEF = 0,
    IDX_LORESERVE = 0xFF00,
    IDX_HIRESERVE = 0xFFFF
  };

  enum type_t
  {
    TYPE_NULL = 0,
    TYPE_PROGBITS = 1,
    TYPE_SYMTAB = 2,
    TYPE_STRTAB = 3,
    TYPE_RELA = 4,
    TYPE_HASH = 5,
    TYPE_DYNAMIC = 6,
    TYPE_NOTE = 7,
    TYPE_NOBITS = 8,
    TYPE_REL = 9,
    TYPE_SHLIB = 10,
    TYPE_DYNSYM = 11
  };

  enum flag_t
  {
    FLAG_WRITE = 1,
    FLAG_ALLOC = 2,
    FLAG_EXECINSTR = 4
  };

  u32_t name;
  u32_t type;
  u64_t flags;
  u64_t addr;
  u64_t offset;
  u64_t size;
  u32_t link;
  u32_t info;
  u64_t addralign;
  u64_t entsize;
} PACKED;

END_NAMESPACE

#endif /* HEADER_ELF_ELF_HH */

